<?php
namespace app\common\logic;

use app\common\base\Errors;
use app\common\base\Menu;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use app\common\model\admin\RoleModel;
use app\common\model\admin\AdminModel;
use app\common\exception\BaseException;

class AuthLogic
{

    /**
     * 登录
     *
     * @param string $user
     * @param string $pwd
     *
     * @throws
     *
     * @return int
     */
    public function login($user = '', $pwd = '')
    {
        $user = trim($user); if($user == ''){ throw new BaseException(1001, Errors::$codes[1001]); }
        $pwd = trim($pwd); if($pwd == ''){ throw new BaseException(1002, Errors::$codes[1002]); }
        $info = AdminModel::getInstance()->getAdmin(4, ['user'=>trim($user)]);
        if(empty($info)){ throw new BaseException(1004, Errors::$codes[1004]); }
        if($info['st'] < 1){ throw new BaseException(1003, Errors::$codes[1003]); }
        if($info['pwd'] != md5($pwd)){ throw new BaseException(1005, Errors::$codes[1005]); }
        return $info['id'];
    }

    /**
     * 生成 JWT token
     *
     * @param int  $id
     * @param bool $jwt_to_string
     *
     * @throws
     *
     * @return string
     */
    public function createToken($id = 0, $jwt_to_string = true)
    {
        $id = intval($id); if($id < 1){ throw new BaseException(2001, Errors::$codes[2001]); }
        $info = AdminModel::getInstance()->getAdmin(4, ['id'=>$id]);
        if(empty($info)){ throw new BaseException(1004, Errors::$codes[1004]); }
        if($info['st'] < 1){ throw new BaseException(1003, Errors::$codes[1003]); }
        //限制用户生成 jwt 频率 【to be continue】
        //生成 jwt
        $jwt = (new Builder())
            ->setExpiration(TS + 86400)
            ->set('id', $id)
            ->sign((new Sha256()), config('jwt_secret'))
            ->getToken();
        return $jwt_to_string ? $jwt->__toString() : $jwt;
    }

    /**
     * 获取 JWT token
     *      1.从 header 中取得
     *      2.从 $_POST 中取得
     *      3.从 $_GET  中取得
     *
     * @param string $name
     *
     * @return string
     */
    public function getToken($name = 'Authorization')
    {
        // header 中
        $token = request()->header($name);
        $token = trim($token);
        // $_POST[' $name ']
        if($token == ''){
            $token = input('post.'.$name, '');
            $token = trim($token);
        }
        // $_GET[' $name ']
        if($token == ''){
            $token = input('get.'.$name, '');
            $token = trim($token);
        }
        return $token;
    }

    /**
     * 获取可用菜单
     *
     * @param string $role
     *
     * @throws
     *
     * @return string
     */
    public function getMenuRouter($role = '')
    {
        $role = trim($role); if($role == ''){ throw new BaseException(1007, Errors::$codes[1007]); }
        $menu = Menu::$menu;
        $group = RoleModel::getInstance()->getRole(4, ['role'=>$role]);
        $pri = $group['pri'] ? json_decode($group['pri'], true) : [];

        //从树中提取所有路由
        $router = tree_to_array($menu, 'name');

        //剔除树中不是菜单的节点,并标记节点层级
        foreach($menu as $k => $m) {
            $menu[$k]['lv'] = 1;
            if($m['type'] != 'menu') unset($menu[$k]);
            if( ! isset($m['subs'])){ $m['subs'] = []; }//避免报错
            if($m['subs']) {
                foreach($m['subs'] as $t => $m2) {
                    $menu[$k]['subs'][$t]['lv'] = 2;
                    if($m2['type'] != 'menu') unset($menu[$k]['subs'][$t]);
                    if( ! isset($m2['subs'])){ $m2['subs'] = []; }//避免报错
                    if($m2['subs']) {
                        foreach($m2['subs'] as $j => $m3) {
                            $menu[$k]['subs'][$t]['subs'][$j]['lv'] = 3;
                            if($m3['type'] != 'menu') unset($menu[$k]['subs'][$t]['subs'][$j]);
                        }
                    }
                }
            }
        }

        if($role == 'admin') {
            return ['router' => $router, 'menu' => $menu];   //超管可用所以路由和菜单
        }

        //去除无权限的菜单
        foreach($menu as $k => $lv1) {
            if( ! isset($lv1['subs'])) {
                if( ! in_array($lv1['name'], $pri)) {
                    unset($menu[$k]);
                }
            }else{
                foreach($lv1['subs'] as $t => $lv2) {
                    if( ! $lv2['subs']) {
                        if( ! in_array($lv2['name'], $pri)) {
                            unset($menu[$k]['subs'][$t]);
                        }
                    }else{
                        foreach($lv2['subs'] as $j => $lv3) {
                            if( ! in_array($lv3['name'], $pri)) {
                                unset($menu[$k]['subs'][$t]['subs'][$j]);
                            }
                        }
                    }
                }
            }
        }


        //去除空2级菜单
        foreach($menu as $k => $lv1) {
            if(isset($lv1['subs'])) {
                foreach($lv1['subs'] as $t => $lv2) {
                    if($lv2['subs'] === [])  unset($menu[$k]['subs'][$t]);
                }
            }
        }

        //去除空一级菜单
        foreach($menu as $k => $lv1) {
            if(isset($lv1['subs']) && $lv1['subs'] === []) unset($menu[$k]);
        }

        //三级菜单重排key,否则丢给前端的有时是数组有时是对象
        $menu = array_values($menu);
        foreach($menu as &$lv1) {
        	if($lv1['subs']) {
		        $lv1['subs'] = array_values($lv1['subs']);
		        foreach($lv1['subs'] as &$lv2) {
			        if($lv2['subs']) $lv2['subs'] = array_values($lv2['subs']);
		        }
	        }
        }

        return ['router' => $pri, 'menu' => $menu];
    }
}
